/*
 * Copyright (C) 2016 Nishant Srivastava
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package github.nisrulz.easydeviceinfo.base;

import ohos.aafwk.ability.Ability;
import ohos.agp.window.service.Display;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.global.configuration.Configuration;
import ohos.security.SystemPermission;
import ohos.security.permission.NeedsPermission;
import ohos.system.DeviceInfo;
import ohos.system.version.SystemVersion;
import ohos.telephony.RadioInfoManager;
import ohos.telephony.SimInfoManager;

import java.io.File;
import java.util.Locale;
import java.util.Optional;

import github.nisrulz.easydeviceinfo.common.EasyDeviceInfo;

/**
 * EasyDevice Mod Class
 *
 * @since 2021-06-10
 */
public class EasyDeviceMod {
    private final RadioInfoManager tm;
    private final SimInfoManager sm;
    private final Context context;

    /**
     * Instantiates a new Easy  device mod.
     *
     * @param context the context
     */
    public EasyDeviceMod(final Context context) {
        this.context = context;
        tm = RadioInfoManager.getInstance(context);
        sm = SimInfoManager.getInstance(context);

    }

    /**
     * Gets phone no.
     * <p>
     * You need to declare the below permission in the manifest file to use this properly
     * <p>
     * SystemPermission.GET_TELEPHONY_STATE
     *
     * @return the phone no
     */
    @NeedsPermission(SystemPermission.GET_TELEPHONY_STATE)
    public final String getPhoneNo() {
        String result = null;
        if (PermissionUtil.hasPermission(context, SystemPermission.GET_TELEPHONY_STATE)
            && sm.getSimTelephoneNumber(sm.getDefaultVoiceSlotId()) != null) {
            result = sm.getSimTelephoneNumber(sm.getDefaultVoiceSlotId());
        }

        return CheckValidityUtil.checkValidData(result);
    }

    /**
     * Gets product.
     *
     * @return the product
     */
    public final String getProduct() {
        return CheckValidityUtil.checkValidData(DeviceInfo.getName());
    }

    /**
     * Gets language.
     *
     * @return the language
     */
    public final String getLanguage() {
        return CheckValidityUtil.checkValidData(Locale.getDefault(Locale.Category.DISPLAY).getLanguage());
    }

    /**
     * Device type int.
     *
     * @param activity the activity
     * @return the int
     */

    @DeviceType
    public final int getDeviceType(Ability activity) {
        DisplayManager displayManager = DisplayManager.getInstance();
        Optional<Display> defaultDisplay = displayManager.getDefaultDisplay(context);
        double diagonalInches = 0;
        if (defaultDisplay.isPresent()) {
            double yInches = defaultDisplay.get().getAttributes().height / defaultDisplay.get().getAttributes().yDpi;
            double xInches = defaultDisplay.get().getAttributes().width / defaultDisplay.get().getAttributes().xDpi;
            diagonalInches = Math.sqrt(xInches * xInches + yInches * yInches);
        }
        if (diagonalInches > 10.1) {
            return DeviceType.TV;
        } else if (diagonalInches <= 10.1 && diagonalInches > 7) {
            return DeviceType.TABLET;
        } else if (diagonalInches <= 7 && diagonalInches > 6.5) {
            return DeviceType.PHABLET;
        } else if (diagonalInches <= 6.5 && diagonalInches >= 2) {
            return DeviceType.PHONE;
        } else {
            return DeviceType.WATCH;
        }
    }

    /**
     * Gets model.
     *
     * @return the model
     */
    public final String getModel() {
        return CheckValidityUtil.checkValidData(
            CheckValidityUtil.handleIllegalCharacterInResult(DeviceInfo.getModel()));
    }

    /**
     * Gets screen display id.
     *
     * @return the screen display id
     */
    public final String getScreenDisplayID() {
        DisplayManager wm = DisplayManager.getInstance();
        if (wm != null) {
            Optional<Display> display = wm.getDefaultDisplay(context);
            return CheckValidityUtil.checkValidData(String.valueOf(display.isPresent() ? display.get().getDisplayId() : ""));
        }
        return CheckValidityUtil.checkValidData(EasyDeviceInfo.notFoundVal);
    }

    /**
     * Gets build version sdk.
     *
     * @return the build version sdk
     */
    public final int getBuildVersionSDK() {

        return SystemVersion.getApiVersion();
    }

    /**
     * Is Device rooted boolean.
     *
     * @return the boolean
     */
    public final boolean isDeviceRooted() {
        String su = "su";
        String[] locations = {
            "/sbin/", "/system/bin/", "/system/xbin/", "/system/sd/xbin/", "/system/bin/failsafe/",
            "/data/local/xbin/", "/data/local/bin/", "/data/local/"
        };
        for (String location : locations) {
            if (new File(location + su).exists()) {
                return true;
            }
        }
        return false;
    }

    /**
     * Gets IMEI number
     * <p>
     * You need to declare the below permission in the manifest file to use this properly
     * <p>
     * SystemPermission.GET_TELEPHONY_STATE
     *
     * @return the imei
     */
    @NeedsPermission(SystemPermission.GET_TELEPHONY_STATE)
    public final String getIMEI() {
        String result = null;
        if (PermissionUtil.hasPermission(context, SystemPermission.GET_TELEPHONY_STATE)) {
            result = tm.getImei(sm.getDefaultVoiceSlotId());
        }
        return CheckValidityUtil.checkValidData(result);
    }

    /**
     * Gets os codename.
     *
     * @return the os codename
     */
    public final String getOSCodename() {
        String codename = SystemVersion.getReleaseType();
        return CheckValidityUtil.checkValidData(codename);
    }

    /**
     * Gets os version.
     *
     * @return the os version
     */
    public final String getOSVersion() {
        return CheckValidityUtil.checkValidData(String.valueOf(SystemVersion.getMajorVersion()));
    }

    /**
     * Gets orientation.
     *
     * @param activity the activity
     * @return the orientation
     */
    @OrientationType //horizontal==1 vertical=0
    public final int getOrientation(final Ability activity) {
        switch (activity.getResourceManager().getConfiguration().direction) {
            case Configuration
                .DIRECTION_VERTICAL:
                return OrientationType.PORTRAIT;
            case Configuration.DIRECTION_HORIZONTAL:
                return OrientationType.LANDSCAPE;
            default:
                return OrientationType.UNKNOWN;
        }
    }
}
